using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;


namespace Miao.DataFormat
{
    public static class CsvParser
    {

        private readonly static Dictionary<string, Action<FieldInfo, object, string>> CustomAnalyticalDictionary = new Dictionary<string, Action<FieldInfo, object, string>>();

        public static void AddCustomAnalyticalFunction(Type type, Action<FieldInfo, object, string> function)
        {
            if (CustomAnalyticalDictionary.TryAdd(type.FullName, function))
            {
                return;
            }
            throw new Exception("解析类型 " + type.FullName + " 已有一个解析方法, 不能重复添加!");
        }
        /// <summary>
        /// 解析拥有基础标准格式的CSV
        /// 只支持字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="csvText"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static List<T> ParseBasicCSV<T>(string csvText) where T : new()
        {
            List<T> result = new List<T>();
            string[] lines = csvText.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            if (lines.Length == 0) return result;

            // 处理标题行
            //List<string> headers = SplitCsvLine(lines[0]);
            string[] headers = lines[0].Split(',', StringSplitOptions.RemoveEmptyEntries);
            FieldInfo[] field = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            Dictionary<int, FieldInfo> columnMap = new Dictionary<int, FieldInfo>();

            for (int i = 0; i < headers.Length; i++)
            {
                string header = headers[i];
                foreach (var prop in field)
                {
                    if (prop.Name.Equals(header, StringComparison.OrdinalIgnoreCase))
                    {
                        columnMap[i] = prop;
                        break;
                    }
                }
            }

            // 处理数据行
            foreach (var line in lines.Skip(1))
            {
                if (string.IsNullOrWhiteSpace(line)) continue;

                List<string> fields = SplitCsvLine(line);
                T obj = new T();

                foreach (var kvp in columnMap)
                {
                    int colIndex = kvp.Key;
                    FieldInfo prop = kvp.Value;

                    if (colIndex >= fields.Count) continue;

                    string value = fields[colIndex];
                    if (string.IsNullOrEmpty(value)) continue;

                    try
                    {
                        if (CustomAnalyticalDictionary.TryGetValue(prop.FieldType.FullName, out var call))
                        {
                            call.Invoke(prop, obj, value);
                        }
                        else
                        {
                            prop.SetValue(obj, value);
                        }
                    }
                    catch
                    {
                        // 处理转换失败（可选）
                        throw new Exception($"解析类型{obj}的{prop.Name}失败，值为{value}");
                    }
                }

                result.Add(obj);
            }

            return result;
        }



        private static List<string> SplitCsvLine(ReadOnlySpan<char> line)
        {
            List<string> fields = new List<string>();
            int start = 0;
            int bracketLevel = 0;//进入等级

            for (int i = 0; i < line.Length; i++)
            {
                switch (line[i])
                {

                    case '(':
                    case '[':
                    case '{':

                        bracketLevel++;

                        break;
                    case ')':
                    case ']':
                    case '}':

                        bracketLevel--;

                        break;
                    case ',' when bracketLevel == 0:
                        fields.Add(line.Slice(start, i - start).ToString());
                        start = i + 1;
                        break;
                }
            }

            fields.Add(line.Slice(start).ToString()); // 添加最后一个字段
            return fields;
        }
        /// <summary>
        /// 解析自定义化的CSV格式，现支持csv需求的子链表格式。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="csvText"></param>
        /// <returns></returns>
        public static List<T> ParseCSV<T>(string csvText) where T : new()
        {

            //string[] lines = csvText.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
            string[] lines = Regex.Split(csvText, @"\r\n|\r|\n");

            // 处理标题行
            //List<string> headers = SplitCsvLine(lines[0]);
            string[] headers = lines[0].Split(',', StringSplitOptions.RemoveEmptyEntries);
            FieldInfo[] fieldTest = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            Dictionary<int, FieldInfo> columnMap = new Dictionary<int, FieldInfo>();

            for (int i = 0; i < headers.Length; i++)//所有可映射赋值对象
            {

                for(int j = 0;j< fieldTest.Length;j++)
                {
                    if (fieldTest[j].Name.Equals(headers[i], StringComparison.OrdinalIgnoreCase))
                    {

                        columnMap[i] = fieldTest[j];
                        break;
                    }

                }
            }
            List<T> tResult = new List<T>();

            // 处理数据行
            foreach (var line in lines.Skip(1))
            {
                if (string.IsNullOrWhiteSpace(line)) continue;

                int index = 0;
                MiaoListData lineData = RecursiveDeserialize(line,ref index);
                T obj = new T();

                foreach (var FData in columnMap)
                {
                    int colIndex = FData.Key;
                    FieldInfo prop = FData.Value;//根据FieldInfo来强转

                    if (colIndex >= lineData.Count()) continue;
                    switch (lineData[colIndex].type)
                    {
                        case DataType.List:
                            MiaoListData miaoListData = lineData[colIndex] as MiaoListData;
                            if (miaoListData != null)
                            {
                                IList list = CreateList(miaoListData, prop);//再解析一层，直到基础类型添加
                                prop.SetValue(obj, list);
                            }
                            break;
                        case DataType.Basic:
                            MiaoBasicData miaoBasicData = lineData[colIndex] as MiaoBasicData;
                            if (!string.IsNullOrEmpty(miaoBasicData.value))
                            {
                                try
                                {
                                    if (prop.FieldType.IsEnum)
                                    {
                                        var enumValue = Enum.Parse(prop.FieldType, miaoBasicData.value);
                                        prop.SetValue(obj, enumValue);
                                    }
                                    else
                                    {
                                        switch (Type.GetTypeCode(prop.FieldType))
                                        {
                                            case TypeCode.Int32:
                                                prop.SetValue(obj, int.Parse(miaoBasicData.value));
                                                break;
                                            case TypeCode.Int64:
                                                prop.SetValue(obj, long.Parse(miaoBasicData.value));
                                                break;
                                            case TypeCode.Single:
                                                prop.SetValue(obj, float.Parse(miaoBasicData.value));
                                                break;
                                            case TypeCode.Double:
                                                prop.SetValue(obj, double.Parse(miaoBasicData.value));
                                                break;
                                            case TypeCode.String:
                                                var st = miaoBasicData.value;
                                                prop.SetValue(obj, st);
                                                break;
                                            default:
                                                throw new Exception($"未识别的基本类型{prop.FieldType}");
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Debug.LogError($"错误{ex.Message}转换失败{miaoBasicData.value}他视为{prop.FieldType},请检查是否由于逗号导致错位");
                                }
                            }
                            break;
                    }

                }

                tResult.Add(obj);
            }

            return tResult;
        }
        public static IList CreateList(MiaoListData miaoListData, FieldInfo fileInfo)
        {
            Type listType = fileInfo.FieldType;
            IList list = (IList)Activator.CreateInstance(listType);
            Type objectType = listType.GenericTypeArguments[0];
            foreach (MiaoParserData item in miaoListData)
            {
                if (item is MiaoBasicData basicData)
                {
                    list.Add(basicData.value);
                }
                //TODO,处理非基本类型
            }
            return list;
        }

        private static MiaoListData RecursiveDeserialize(ReadOnlySpan<char> line, ref int index)
        {
            MiaoListData miaoListData = new MiaoListData();
            int start = index;

            for (; index < line.Length; index++)
            {
                if (line[index] == '{')
                {
                    index++; // 跳过{
                    MiaoListData childList = RecursiveDeserialize(line, ref index);
                    miaoListData.AddElement(childList);
                    start = index + 1; // 跳过处理完成的逗号
                }
                else if (line[index] == '}')
                {
                    // 处理闭合前的最后一个字段
                    if (index > start)
                    {
                        string basicValue = new string(line.Slice(start, index - start));
                            miaoListData.AddElement(new MiaoBasicData(basicValue));
                    }
                    //虽然}已经结束，但要捕获到该项逗号才回归上级
                    while(line[index] != ',')
                    {
                        index++;
                    }
                    return miaoListData;
                }
                else if (line[index] == ',')
                {

                    // 处理当前字段（包括空字段）
                    string value = new string(line.Slice(start, index - start));
                    miaoListData.AddElement(new MiaoBasicData(value));
                    start = index + 1; // 跳过处理完成的逗号
                }
            }

            // 处理最后一个字段（如果有）
            if (start < line.Length)
            {
                string lastValue = new string(line.Slice(start));
                    miaoListData.AddElement(new MiaoBasicData(lastValue));
            }
            return miaoListData;
        }

        //private static MiaoListData RecursiveDeserialize(ReadOnlySpan<char> line, ref int index)
        //{
        //    MiaoListData miaoListData = new MiaoListData();
        //    int start = index;

        //    for (; index < line.Length; index++)
        //    {
        //        char c = line[index];
        //        if (c == '{')
        //        {
        //            //inBasic = false;
        //            //bracketLevel++;
        //            index++; // 跳过{
        //            MiaoListData childList = RecursiveDeserialize(line, ref index);//开始读逗号内容
        //            miaoListData.AddElement(childList);
        //            //子项读取完毕跳过" }",中的}"
        //            while (line[index] !=',')
        //            {
        //                index++;
        //            }
        //            start = index + 1;
        //        }
        //        else if (c == '}')//发现自己是子集
        //        {
        //                    string basicValue = new string(line.Slice(start, index - start));
        //                    if (!string.IsNullOrEmpty(basicValue))
        //                    miaoListData.AddElement(new MiaoBasicData(basicValue));
        //                return miaoListData;
        //        }
        //        else if (c == ',')
        //        {
        //            if (index > start)
        //            {
        //                string value = new string(line.Slice(start, index - start));
        //                //if (!string.IsNullOrEmpty(value))
        //                miaoListData.AddElement(new MiaoBasicData(value));
        //            }
        //            start = index + 1; // 跳过逗号
        //        }
        //    }

        //    // 处理最后一个字段
        //    //if (start < line.Length)
        //    //{
        //    //    string lastValue = new string(line.Slice(start));
        //    //    if (!string.IsNullOrEmpty(lastValue))
        //    //        miaoListData.AddElement(new MiaoBasicData(lastValue));
        //    //}
        //    return miaoListData;
        //}


    }
}